package cn.pugle.base.uri_encode;

import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import cn.pugle.httpcomponent.ClientUtils;

/**
 * sohu 生成签名的时候要求按照RFC3986标准进行encode ~ 保留。 和java中的URLEncoder不一样.u
 * java urlEncode 和httpcomponet的util 都是用来encode x-www-form-urlencoded 的， 遵循html的指南。 和uri的rfc不一样，用处不同
 * uri本身又是一个坑。使用多参数的构造函数时， 会encode传进去的query， 但encode的很屎。推荐用builder
 * Created by tzp on 16-9-1.
 */
public class UriEncodeTest {
    private static String key_auth_consumer_key = "auth_consumer_key";
    private static String key_auth_nonce = "auth_nonce";
    private static String key_auth_signature_method = "auth_signature_method";
    private static String key_auth_signature = "auth_signature";
    private static String key_customer_key = "customer_key";
    private static String key_auth_timestamp = "auth_timestamp";

    //for post3
    public static String generateSignature(String method, URI uri, List<NameValuePair> params) throws Exception {
        String sbBaseString = getSBBaseString(method, uri, params);
        System.out.println("baseString:  " + sbBaseString);
        byte[] signatureBytes = EncryptUtil.sha(sbBaseString, "xx");
        String signature = EncryptUtil.encodeBase64(signatureBytes, "UTF-8");
        return signature;
    }

    //for post 数字签名的源 text
    private static String getSBBaseString(String method, URI uri, List<NameValuePair> params)
            throws Exception {
//        String format = URLEncodedUtils.format(params, "UTF-8");//xxx
//        String query = encodeURIComponent(format);
//        String query = URLEncoder.encode(format, "UTF-8");

        String normalizeQuery = paramsToEncodeQuery(params);
        String query = encodeURIComponent(normalizeQuery);

        String baseURI = getURIString(uri);
        baseURI = encodeURIComponent(baseURI);

        String source = String.format(method + "&%s&%s", baseURI, query);
        return source;
    }

    public static String paramsToEncodeQuery(List<NameValuePair> params) {
        StringBuilder queryParam = new StringBuilder("");
        for (NameValuePair param : params) {
            queryParam.append(encodeURIComponent(param.getName())).append("=").append(encodeURIComponent(param.getValue())).append("&");
        }
        queryParam.deleteCharAt(queryParam.length() - 1);
        return queryParam.toString();
    }

    public static String paramsToRawQuery(List<NameValuePair> params) {
        StringBuilder queryParam = new StringBuilder("");
        for (NameValuePair param : params) {
            queryParam.append(param.getName()).append("=").append(param.getValue()).append("&");
        }
        queryParam.deleteCharAt(queryParam.length() - 1);
        return queryParam.toString();
    }

    private static String getURIString(URI uri) {
        return uri.getScheme() + "://" + uri.getHost() + uri.getPath();
    }

    public static String encodeURIComponent(String s) {
        String result = null;
        try {
            result = URLEncoder.encode(s, "UTF-8")
//                    .replaceAll("\\+", "%20")
//                    .replaceAll("\\%21", "!")
//                    .replaceAll("\\%27", "'")
//                    .replaceAll("\\%28", "(")
//                    .replaceAll("\\%29", ")")
                    .replaceAll("\\%7E", "~");
        }// This exception should never occur.
        catch (UnsupportedEncodingException e) {
            result = s;
        }
        return result;
    }


    private static String postStringForm(URI uri, List<NameValuePair> params) {
        HttpPost post = new HttpPost(uri);
        post.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        try {
//            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");//xxx
//            FormEntity entity = new FormEntity(params, "UTF-8");
            FormURIEncodeEntity entity = new FormURIEncodeEntity(params, "UTF-8");
            post.setEntity(entity);

            System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
            System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
            System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "DEBUG");
            String response = ClientUtils.execute(HttpClients.createDefault(), post);

            return response;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


}
